package easier.app.x;

import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.res.Configuration;
import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;
import androidx.collection.ArrayMap;
import androidx.lifecycle.Lifecycle.Event;
import androidx.lifecycle.Lifecycle.State;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.OnLifecycleEvent;

/**
 * 管理activity和fragment的独立于生命周期的数据,同时可以用于和Activity/Fragment通信
 */
public abstract class LifecycleModel {

    /**
     * 保存所有数据类,数据类保存在这里,独立于生命周期,需要的时候拉取数据显示
     */
    protected static ArrayMap< Object, ModelWithLife< ? extends LifecycleOwner > > sModels = new ArrayMap<>();

    /**
     * 数据类,保存所有需要的数据
     *
     * @param <T> activity或者fragment
     */
    public static abstract class ModelWithLife< T extends LifecycleOwner > implements LifecycleObserver, ComponentCallbacks2 {

        protected Object key;
        //用于显示数据的界面,同时可以用于通信
        protected T mViewHost;

        public ModelWithLife() {

        }

        public T getViewHost() {

            return mViewHost;
        }

        public void addToLifecycle( T owner ) {

            /* 监听生命周期 */
            owner.getLifecycle().removeObserver( this );
            owner.getLifecycle().addObserver( this );

            mViewHost = owner;

            /* 监听内存 */
            if ( owner instanceof Context ) {
                ((Context) owner).registerComponentCallbacks( this );
            }
        }

        @OnLifecycleEvent( Event.ON_CREATE )
        public void onViewCreate() {

        }

        @OnLifecycleEvent( Event.ON_START )
        public void onViewStart() {

        }

        @OnLifecycleEvent( Event.ON_RESUME )
        public void onViewResume() {

        }

        @OnLifecycleEvent( Event.ON_PAUSE )
        public void onViewPause() {

        }

        @OnLifecycleEvent( Event.ON_STOP )
        public void onViewStop() {

        }

        @CallSuper
        @OnLifecycleEvent( Event.ON_DESTROY )
        public void onViewDestroy() {

            mViewHost = null;
            clearInstance();
        }

        /**
         * 销毁实例
         */
        @CallSuper
        public void clearInstance() {

            LifecycleModel.destroyInstance( this );
        }

        /**
         * @return 获取当前状态
         */
        public State getLifecycleCurrentState() {

            if ( mViewHost == null ) {
                return State.DESTROYED;
            } else {
                return mViewHost.getLifecycle().getCurrentState();
            }
        }

        @Override
        public void onConfigurationChanged( @NonNull Configuration newConfig ) {

        }

        @Override
        public void onLowMemory() {

        }

        @Override
        public void onTrimMemory( int level ) {

            /* 内存不足，并且该进程的UI已经不可见了。 */
            if ( level == TRIM_MEMORY_UI_HIDDEN ) {
                /* save instance here */
            }
        }
    }

    /**
     * 获取数据类
     *
     * @param vmClass 数据类,用于实例化
     * @param <E>     数据类型绑定的activity或者fragment
     * @param <VM>    数据类
     *
     * @return 数据类
     */
    public static < E extends LifecycleOwner, VM extends ModelWithLife< E > > VM getInstance( Class< VM > vmClass ) {

        return getInstance( vmClass.getName(), vmClass );
    }

    /**
     * 获取数据类
     *
     * @param vmClass 数据类,用于实例化
     * @param <E>     数据类型绑定的activity或者fragment
     * @param <VM>    数据类
     * @param owner   activity 或者fragment
     *
     * @return 数据类
     */
    public static < E extends LifecycleOwner, VM extends ModelWithLife< E > > VM getInstance( Class< VM > vmClass, E owner ) {

        return getInstance( vmClass.getName(), vmClass, owner );
    }

    /**
     * 获取数据类
     *
     * @param key     数据类唯一标识
     * @param vmClass 数据类,用于实例化
     * @param <E>     数据类型绑定的activity或者fragment
     * @param <VM>    数据类
     *
     * @return 数据类
     */
    public static < E extends LifecycleOwner, VM extends ModelWithLife< E > > VM getInstance( Object key, Class< VM > vmClass ) {

        ModelWithLife< ? extends LifecycleOwner > model = sModels.get( key );

        if ( model == null ) {
            try {
                VM vm = vmClass.newInstance();
                vm.key = key;
                sModels.put( key, vm );
                return vm;
            } catch ( Exception e ) {
                throw new NullPointerException( e.getMessage() );
            }
        } else {
            try {
                return vmClass.cast( model );
            } catch ( Exception e ) {
                model.clearInstance();
                sModels.remove( key );
                return getInstance( key, vmClass );
            }
        }
    }

    public static < E extends LifecycleOwner, VM extends ModelWithLife< E > > VM getInstance( Object key, Class< VM > vmClass,
        E owner ) {

        VM instance = getInstance( key, vmClass );
        instance.addToLifecycle( owner );

        return instance;
    }

    /**
     * @param instance 彻底销毁该实例
     */
    public static < E extends LifecycleOwner, VM extends ModelWithLife< E > > void destroyInstance( VM instance ) {

        sModels.remove( instance.key, instance );
    }
}
